#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import os
import numpy as np
import logging

from common import replace_id
from analysis_describe_file import FileAnalysis
from variables import Variables
from multithread import multithread

class LoadCase(object):
    def __init__(self, lc_path):

        self.lc_path = lc_path
        self.lc_name = os.path.basename(lc_path)
        self.lc_id = replace_id(self.lc_name)
        self.__analysis__()

    def __analysis__(self):
        self.file_analysis={}
        for s in self.__file_analysis__():
            self.file_analysis.update(s)
        self.variables = {}
        for v in self.__variables__():
            k = v.variable_name
            if self.variables.has_key(k):
                self.variables[k]['genlab'].append(v.genlab)
            else:
                self.variables.update({
                    k:{
                        'id':v.variable_id,
                        'unit':v.variable_unit,
                        'genlab':[v.genlab]
                    }
                })

        self.max_section = self.__max_section__()

    def binary_files(self):
        groups=[]
        for p in os.listdir(self.lc_path):
            real_path = os.path.join(self.lc_path,p)
            if os.path.isfile(real_path) and '.$' in p:
                groups.append(real_path)
        return groups

    @property
    def describe_files(self):
        groups=[]
        for p in os.listdir(self.lc_path):
            real_path = os.path.join(self.lc_path,p)
            if os.path.isfile(real_path) and '.%' in p:
                groups.append(real_path)
        return groups

    def __variables__(self):
        for f,fa in self.file_analysis.items():
            for v in fa.variables:
                yield Variables(fa,v)

    def __file_analysis__(self):
        for fa in self.describe_files:
            yield {fa:FileAnalysis(fa)}
        # for rs in  multithread(FileAnalysis, self.describe_files):
        #     yield {rs.describe_file: rs}

    def __max_section__(self):
        section = 1
        for df,df_v in self.file_analysis.items():
            if df_v.section > section:
                section = df_v.section
        return section

    def save_bigndarray(self,f_path):

        if os.path.exists(f_path):
            logging.info("%s is exist, skip."%f_path)
            return
        #sorted file by name
        files_list = sorted(self.describe_files)
        vars_list = []

        #get all variables
        for key in files_list:
            vars_list.extend(self.file_analysis[key].variables)

        if len(vars_list) == 0 :
            logging.error(
                "loadcase %s has none variables."%self.lc_name)
            return

        if 'Time from start of output' not in vars_list:
            logging.error("loadcase %s 'Time from start of output' not in variables"%self.lc_name)
            return

        for k in ["Tower_station_height","Blade_station_radius","sectionId","sectionMax","ts"]:
            vars_list.insert(0, k)

        #get maxrow num  on section0
        maxrow_on_section0 = 0
        maxrow_on_section = 0
        maxsection = 0
        tower_axivals = []
        blade_axivals = []

        for key in files_list:
            fa = self.file_analysis[key]
            if fa.section == 0:
                if fa.dimens[-1] > maxrow_on_section0:
                    maxrow_on_section0 = fa.dimens[-1]
            else:
                if fa.dimens[-1] > maxrow_on_section:
                    maxrow_on_section = fa.dimens[-1]
                if fa.section > maxsection:
                    maxsection = fa.section
                if fa.genlab == 'Tower loads GL coordinates':
                    tower_axivals = fa.axivals
                elif fa.genlab == 'Blade 1 Loads':
                    blade_axivals = fa.axivals

        temp_ndarray = np.full((maxrow_on_section0+maxrow_on_section*maxsection,len(vars_list)),np.NAN)
        for key in files_list:
            fa = self.file_analysis[key]
            fa_ndarray = fa.ndarray()
            var0 = fa.variables[0]
            col_start = vars_list.index(var0)
            col_end = col_start + len(fa.variables)
            if fa.section == 0:
                row_start = 0
            else:
                row_start = maxrow_on_section0

                if fa.section == 1:
                    if 'Tower' in fa.genlab:
                        index = tower_axivals.index(fa.axivals[0])
                        row_start = maxrow_on_section0+index*maxrow_on_section
                    elif 'Blade' in fa.genlab:
                        index = blade_axivals.index(fa.axivals[0])
                        row_start = maxrow_on_section0+index*maxrow_on_section

            row_end = row_start+fa_ndarray.shape[0]

            temp_ndarray[row_start:row_end,col_start:col_end] = fa_ndarray

        #ts
        time_index = vars_list.index('Time from start of output')
        time_ndarray = temp_ndarray[:maxrow_on_section0,time_index:time_index+1]
        temp_ndarray[:maxrow_on_section0, 0:1] = time_ndarray
        temp_ndarray[:1,:1] = 0
        for num in range(0,maxsection):
            row_start = maxrow_on_section0+num*maxrow_on_section
            row_end = row_start + maxrow_on_section
            temp_ndarray[row_start:row_end,0:1] = time_ndarray

        #sectionMax
        temp_ndarray[:maxrow_on_section0,1:2]=0
        temp_ndarray[maxrow_on_section0:,1:2]=maxsection
        #sectionId
        temp_ndarray[:maxrow_on_section0,2:3]=0
        for num in range(0, maxsection):
            row_start = maxrow_on_section0+num*maxrow_on_section
            row_end = row_start + maxrow_on_section
            temp_ndarray[row_start:row_end, 2:3] = num+1
        #blade
        for index,value in enumerate(blade_axivals):
            row_start = maxrow_on_section0+index*maxrow_on_section
            row_end = row_start + maxrow_on_section
            temp_ndarray[row_start:row_end, 3:4] = value
        #tower
        for index,value in enumerate(tower_axivals):
            row_start = maxrow_on_section0+index*maxrow_on_section
            row_end = row_start + maxrow_on_section
            temp_ndarray[row_start:row_end, 4:5] = value

        header=[]
        for var in vars_list:
            header.append(replace_id(var))
        np.savetxt(f_path,temp_ndarray,fmt='%.6E',delimiter=',',header=','.join(v for v in header),comments='')
        logging.info("loadcase %s finish."%self.lc_name)

if __name__ == "__main__":
    import sys
    casedir = sys.argv[1]

    loadcase = LoadCase(casedir)
    # for k,v in loadcase.variables.items():
        # print k, v.variable_id, v.describe.describe_file, v.describe.genlab
    loadcase.ndarrayall()